// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef INTRUSION_MANAGER_H_
#define INTRUSION_MANAGER_H_

#include <stdint.h>
#include <stdbool.h>
#include "platform.h"
#include "status/rot_status.h"
#include "intrusion/intrusion_state.h"
#include "intrusion/intrusion_state_observer.h"
#include "crypto/hash.h"
#include "attestation/pcr_store.h"


/**
 * Values that are measured to report intrusion state.
 */
enum {
	INTRUSION_MANAGER_NO_INTRUSION = 0,		/**< No intrusion has been been detected. */
	INTRUSION_MANAGER_INTRUSION = 1,		/**< Intrusion has been detected. */
	INTRUSION_MANAGER_UNKNOWN = 2			/**< The instrusion state is not known. */
};

/**
 * Format version of the intrusion event data.
 */
#define	INTRUSION_MANAGER_MEASUREMENT_VERSION	0


/**
 * Base API for managing intrusions.
 */
struct intrusion_manager {
	/**
	 * Handle an intrusion event.  The system will report that an intrusion has occurred.
	 *
	 * @param manager The intrusion manager to execute the intrusion handling.
	 *
	 * @return 0 if the intrusion was succesfully handled or an error code.
	 */
	int (*handle_intrusion) (struct intrusion_manager *manager);

	/**
	 * Reset the intrusion state.  The system will report no intrusion has occurred.
	 *
	 * @param manager The intrusion manager to execute the reset.
	 *
	 * @return 0 if the intrusion state was successfully reset or an error code.
	 */
	int (*reset_intrusion) (struct intrusion_manager *manager);

	/**
	 * Refresh the current intrusion state and update system reporting appropriately.
	 *
	 * @param manager The intrusion manager to execute the update.
	 *
	 * @return 0 if the update succeeded or an error code.
	 */
	int (*check_state) (struct intrusion_manager *manager);

	struct intrusion_state *state;			/**< The handler for intrusion state. */
	struct hash_engine *hash;				/**< Hash engine for generating measurements. */
	struct pcr_store *pcr;					/**< Storage for intrusion measurement. */
	uint16_t measurement;					/**< Id for the intrusion measurement. */
	struct pcr_measured_data event_data;	/**< Data for the intrusion measurement. */
	platform_mutex lock;					/**< Synchronization for intrusion handling. */
};


int intrusion_manager_init (struct intrusion_manager *manager, struct intrusion_state *state,
	struct hash_engine *hash, struct pcr_store *pcr, uint16_t measurement);
void intrusion_manager_release (struct intrusion_manager *manager);

/* Internal functions for use by derived types. */
int intrusion_manager_update_measurement (struct intrusion_manager *manager, uint8_t value,
	bool force_data);
int intrusion_manager_update_intrusion_state (struct intrusion_manager *manager,
	bool allow_deferred);


#define	INTRUSION_MANAGER_ERROR(code)		ROT_ERROR (ROT_MODULE_INTRUSION_MANAGER, code)

/**
 * Error codes that can be generated by a intrusion manager.
 *
 * Note: Commented error codes have been deprecated.
 */
enum {
	INTRUSION_MANAGER_INVALID_ARGUMENT = INTRUSION_MANAGER_ERROR (0x00),		/**< Input parameter is null or not valid. */
	INTRUSION_MANAGER_NO_MEMORY = INTRUSION_MANAGER_ERROR (0x01),				/**< Memory allocation failed. */
	INTRUSION_MANAGER_INTRUSION_FAILED = INTRUSION_MANAGER_ERROR (0x02),		/**< Intrusion event handling failed. */
	INTRUSION_MANAGER_RESET_FAILED = INTRUSION_MANAGER_ERROR (0x03),			/**< Intrusion state was not reset. */
	INTRUSION_MANAGER_CHECK_FAILED = INTRUSION_MANAGER_ERROR (0x04),			/**< Failed to check the intrusion state. */
};


#endif /* INTRUSION_MANAGER_H_ */
